package org.mihalovic.PES.GUI;

import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

import org.mihalovic.PES.Core.Graph.Rank.*;
import org.mihalovic.PES.data.*;


/**
 * Application's window
 */
public class AppWindow extends JFrame
{
    private static int gap = 4;                             // horizontal gap between GUI components
    private static AppWindow applicationWindow;             // singleton

    private final String RANKS_TAB_TITLE = "Search";        // title of tab for numerical ranking
//del    private final String GRAPH_TAB_TITLE = "Graph";         // title for graphical ranking
    private final String DATA_TAB_TITLE = "Query Data";     // source graph selection

    private DataManager sourceGraphReader;
    private QueryDomainsHolder selectedDomainsHolder;

    private JTabbedPane innerTabPanel;
    private JScrollPane scrollPane;

    private JPanel ranksTabInnerPanel;
    private SourceDataSelectionPanel dataTabInnerPanel;
//    private VisualRankEvaluatorPanel graphTabInnerPanel;



    /**
     * Singleton
     * @return only instance of applications JFrame window
     */
    public static AppWindow getInstance()
    {
        if( applicationWindow==null )
            applicationWindow = new AppWindow("Porada Expert Search v0.1");
        return applicationWindow;
    }


    private AppWindow(String title) {
        super();
        setTitle(title);

        setMinimumSize( new Dimension(830, 555) );
        setLocationByPlatform(true);
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            Logger.getLogger(AppWindow.class.getName()).log(Level.SEVERE, null, e);
        }

        scrollPane = new JScrollPane();
        scrollPane.setMinimumSize( new Dimension(200, 500) );
        
        GridLayout gl = new GridLayout(1, 3);
        gl.setHgap(gap);
        gl.setVgap(gap);
        ranksTabInnerPanel = new JPanel(gl);
        TextRankEvaluatorComponent trec = new TextRankEvaluatorComponent(new PageRankEvaluator());
        ranksTabInnerPanel.add(trec);        

        dataTabInnerPanel = new SourceDataSelectionPanel();
        AddSourceDataChangedListener(dataTabInnerPanel);
        selectedDomainsHolder = new QueryDomainsHolder(/*del dataTabInnerPanel*/);
        selectedDomainsHolder.addQueryChangedListener(trec);
//        graphTabInnerPanel = new VisualRankEvaluatorPanel();

        innerTabPanel = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
        innerTabPanel.addTab(DATA_TAB_TITLE, dataTabInnerPanel);
        innerTabPanel.addTab(RANKS_TAB_TITLE, ranksTabInnerPanel);
//        innerTabPanel.addTab(GRAPH_TAB_TITLE, graphTabInnerPanel);

        add(innerTabPanel);

        pack();
        setVisible(true);
    }


    /**
     * @return <code>QueryDomainsHolder</code> object that access domains selected
     * by user in <code>SourceDataSelectionPanel</code>
     */
    public QueryDomainsHolder GetQueryHolder() {
        return selectedDomainsHolder;
    }


    /**
     * @return Reader used to load graphs data
     */
    public DataManager GetSourceGraphReader(){
        return sourceGraphReader;
    }

    public void SetSourceGraphReader(DataManager reader){
        this.sourceGraphReader = reader;
    }


    java.util.Set<SourceDataChangedListener> sdclSet = new java.util.HashSet<SourceDataChangedListener>();
    public void AddSourceDataChangedListener(SourceDataChangedListener listener){
        sdclSet.add(listener);
    }

    public void RemoveSourceDataChagedListener(SourceDataChangedListener listener){
        sdclSet.remove(listener);
    }

    /*???*/ public void onSourceDataChange(){               //TODO: this is holy bulls**t. Source data CAN'T CHANGE! Once they are loaded, are steady.
        for(SourceDataChangedListener listener : sdclSet)
            listener.SourceDataChanged();
    }


    /**
     * Show message box with error icon
     */
    void Error(String message) {
        JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
    }
}
